import EventHub from "@konghayao/event-hub/src";
import System from "../System";

/** EventHub 允许 on 的事件类型 */
type EventType = "pointerup" | "pointerdown" | "pointermove" | "mousewheel";

/** EventHub 的回调事件 */
type Callback = (e: MouseEventPlus) => void;

/** 鼠标扩展事件 */
class MouseEventPlus
    extends Laya.Event
    implements Laya.LayaEventData<MouseEvent>
{
    System: typeof System;
    constructor(system: typeof System, event: Laya.LayaEventData<MouseEvent>) {
        super();
        Object.assign(this, event);
        this.System = system;
    }
    getCameraCenterPos = () => {
        const { x, y } = Laya.stage.getMousePoint();
        return new Laya.Point(
            x - Laya.stage.width / 2,
            y - Laya.stage.height / 2
        );
    };
    /** 计算世界中心的坐标点 */
    getWorldPos = () => {
        return this.System.Camera.stage.getMousePoint();
    };
}

export class MouseControl extends EventHub<EventType, Callback> {
    System: typeof System;
    constructor(system: typeof System) {
        super();
        this.System = system;
    }

    /** 用于初始化监听 Laya 的事件 */
    init() {
        type listener = (e: Laya.LayaEventData<MouseEvent>) => void;
        const mouseDown: listener = (e) => {
            this.emit("pointerdown", new MouseEventPlus(this.System, e));
        };

        const template: [Laya.EventTypes, listener][] = [
            [Laya.Event.CLICK, mouseDown],
            [Laya.Event.RIGHT_CLICK, mouseDown],
            [
                Laya.Event.MOUSE_UP,
                (e) => {
                    this.emit("pointerup", new MouseEventPlus(this.System, e));
                },
            ],
            [
                Laya.Event.MOUSE_MOVE,
                (e) => {
                    this.emit(
                        "pointermove",
                        new MouseEventPlus(this.System, e)
                    );
                },
            ],
            [
                Laya.Event.MOUSE_WHEEL,
                (e) => {
                    this.emit("mousewheel", new MouseEventPlus(this.System, e));
                },
            ],
        ];
        template.forEach(([key, value]) => {
            Laya.stage.on<MouseEvent>(key, this, value as any);
        });
    }
}
